unit uMessageTargets;

{$mode objfpc}{$H+}

interface

uses
    Classes, SysUtils, contnrs,
    uMessages,
    uInterfaces, uTypes;

type

    { TISMessageTargets }

    TISMessageTargets = class(TObjectList)
    private
    protected
    public
        function AddTarget(ATarget: IISMessageTarget): IISMessageTarget;
        function RemoveTarget(const AID: string): IISMessageTarget;

        function FindByID(const AID: string): Integer;
        function GetTarget(const AID: string): IISMessageTarget; overload;
        function GetTarget(const AIndex: Integer): IISMessageTarget; overload;

        function Broadcast(var AMsg: TISMessage): TISMessage;
    end;


implementation

{ TISMessageTargets }

function TISMessageTargets.AddTarget(ATarget: IISMessageTarget): IISMessageTarget;
begin
    Result := ATarget;
    Add(ATarget as TObject);
end;

function TISMessageTargets.RemoveTarget(const AID: string): IISMessageTarget;
var
    i: Integer;
begin
    i := FindByID(AID);
    if i > -1 then
    begin
        Result := GetTarget(i);
        Self.Delete(i);
    end
    else
        Result := nil;
end;

function TISMessageTargets.FindByID(const AID: string): Integer;
var
    i: Integer;
begin
    Result := -1;
    for i := 0 to Self.Count - 1 do
    begin
        if (Self[i] as IISMessageTarget).MTID = AID then
        begin
            Result := i;
            Break;
        end;
    end;
end;

function TISMessageTargets.GetTarget(const AID: string): IISMessageTarget;
var
    i: Integer;
begin
    i := FindByID(AID);
    if i > -1 then
        Result := GetTarget(i)
    else
        Result := nil;
end;

function TISMessageTargets.GetTarget(const AIndex: Integer): IISMessageTarget;
begin
    Result := Self[AIndex] as IISMessageTarget;
end;

function TISMessageTargets.Broadcast(var AMsg: TISMessage): TISMessage;
var
    i: Integer;
begin
    for i := 0 to Self.Count - 1 do
    begin
        Self.GetTarget(i).ProcessMessage(AMsg as IISMessage);
        if AMsg.Result = msrDone then
        begin
            Break;
        end;
    end;
    Result := AMsg;
end;

end.

